
// new line
// new lien 2
import { performance, PerformanceObserver } from "perf_hooks";
import websocket from 'koa-easy-ws';
import ws from 'ws';
import Koa from "koa";
import Router from "koa-router";
import KoaBodyParser from "koa-bodyparser";
import KoaCompress from "koa-compress";
import { Chance } from "chance";
import moment from 'moment';
import Keyv from 'keyv';
import prettyjson  from 'prettyjson';
const chance = new Chance();
const keyv = new Keyv();

// 过期时间 24 * 60 * 60 * 1000 ms， 24 小时 + ()
async function appendLog(key: string, body: any) {
    const list = await getLog(key);
    list.unshift(body);
    await keyv.set(key, list, 24 * 60 * 60 * 1000); // 
}

// must be [...?]
async function getLog(key: string): Promise<any[]> {
    return await keyv.get(key) ?? [];
}

const PORT = 8879;

//////////////// 埋点测试 ////////////////
const obs = new PerformanceObserver((items) => {
    console.log("PerformanceObserver:", items.getEntries());
    // performance.clearMarks();
});
obs.observe({ entryTypes: ['measure',] });

//////////////// 异常处理 ////////////////
// 监听未捕获的异常
process.on('uncaughtException', function (err) {
    console.error("uncaughtException", err);
});
// 监听Promise没有被捕获的失败函数
process.on('unhandledRejection', function (err, promise) {
    console.error("unhandledRejection", err);
});
//////////////// MAIN ////////////////

const perttyJsonCommonConfig = { noColor: true };

async function runApp() {
    // create koa app
    const app = new Koa();
    const router = new Router();

    router.get("/:log_id", async (context: Koa.Context) => {
        const log_id = context.params.log_id;

        const a_list = {
            "method": context.method,
            "headers":  prettyjson.render(context.headers as any, perttyJsonCommonConfig),
            "params":  prettyjson.render(context.params, perttyJsonCommonConfig),
            "path": context.path,
            "url": context.url,
            "hostname": context.hostname,
            "baseUrl": context.baseUrl,
            "query": JSON.stringify(context.query),
            "originalUrl": context.originalUrl,
        }
        context.body = prettyjson.render(a_list, perttyJsonCommonConfig)
        + "\n\n" + prettyjson.render(await getLog(log_id), perttyJsonCommonConfig)
        return
        // context.body = {msg: a_list}
        context.body = "{msg: a_list}"
            + JSON.stringify([a_list, await getLog(log_id)])
        ;


        // const str_list = a_list.map(item => item[0] + ": " + item[1]).join("\n");
        // const str_logs = (await getLog(log_id)).map(item => moment(item.time).format("YY-MM-DD HH:mm:ss") + "\n" + prettyjson.render(item.info, perttyJsonCommonConfig)).join("\n\n");
        // // const str_logs =  treeify.asTree(await getLog(log_id) as any, true, true);
        // context.body = '<pre style="">' + str_list + "\n\n\nlogs:======================================\n" + str_logs + "</pre>";
    });

    router.post("/:log_id", async (context: Koa.Context) => {
        const log_id = context.params.log_id;
        appendLog(log_id, { time: moment().format("YYYY-MM-DD HH:mm:ss"), info: context.request.body });
        context.body = { success: true, echo: context.request.body  };
    });


    // run app
    app.use(KoaBodyParser({
        formLimit: "10mb",
        jsonLimit: "10mb"
    }));

    // https://github.com/koajs/compress
    app.use(KoaCompress({
        // threshold: 1024 * 1024 // 超过 1MB 自动开启压缩
        br: false, deflate: false,
    }));
    app.use(router.routes());
    app.use(router.allowedMethods());
    const server = app.listen(PORT);

    // 取消超时时间
    // server.setTimeout(1000 * 60 * 30);
    server.setTimeout(0);

    console.log("Koa application is up and running on port " + PORT);
    console.info("Koa application is up and running on port " + PORT);
}

runApp();






// const express = require('express');
// const app = express();
// const port = 80;
// const path = require('path');
// const fs = require("fs");
// const bodyParser = require('body-parser');

// const process = require("process");
// process.on('unhandledRejection', (reason, p) => {
//   console.log('Unhandled Rejection at: Promise', p, 'reason:', reason);
// });

// const server = require('http').createServer({}, app);

// app.use('/static', express.static(path.join(__dirname, "public")));
// const treeify = require('treeify');
// app.use(bodyParser());
// app.use((req, res) => {
//   if (req.method === "GET") {
//     console.log("\n\n\n\n\n");
//     console.log("////////////////////////////////////////////////////////////////");
//     console.log("请求：" + req.url);
//     const a_list = [
//       ["req.method", req.method,],
//       ["req.headers", JSON.stringify(req.headers),],
//       ["req.params", JSON.stringify(req.params),],
//       ["req.path", req.path,],
//       ["req.url", req.url,],
//       ["req.hostname", req.hostname,],
//       ["req.baseUrl", req.baseUrl,],
//       ["req.query", JSON.stringify(req.query),],
//       ["req.originalUrl", req.originalUrl,],
//     ]
//     console.log("a_list", a_list);
//     console.log(treeify.asTree(req.body, true));
//     const str = a_list.map(item => item[0] + ": " + item[1]).join("\n");
//     res.send('<code style="white-space: pre-line;">Hello use now! \n' + str + "</code>");
//   } else if (req.method === "POST") {

//     res.send('{success:true}');
//   }
// });



// server.listen(port, () => {
//   console.log(`App listening at http://127.0.0.1:${port}`)
// });
